// Copyright (C) 2020  Matthew "strager" Glazar
// See end of file for extended copyright information.

"use strict";

let fs = require("fs");
let os = require("os");
let path = require("path");
let process = require("process");
let vscodeTest = require("vscode-test");
let vscodeTestDownload = require("vscode-test/out/download.js");
let { testFilterEnvironmentVariable } = require("./test-support.js");

async function mainAsync() {
  let args = process.argv.slice(2);

  let target = process;
  if (args.length >= 2 && args[0] === "--target") {
    target = parseNodePlatformAndArchitecture(args[1]);
    args = args.slice(2);
  }

  // To make tests consistent across machines, and to allow changing
  // workspace-wide settings, use an empty workspace. (vscode-test doesn't do
  // this for us.)
  let workspacePath = path.resolve(__dirname, "empty_test_workspace");

  let vscodeVersion = getVSCodeVersionForTarget(target);
  let vscodeExePath = await installVSCodeAsync(vscodeVersion, target);
  await vscodeTest.runTests({
    extensionDevelopmentPath: path.resolve(__dirname, ".."),
    extensionTestsPath: path.resolve(__dirname, "vscode-tests.js"),
    version: vscodeVersion,
    vscodeExecutablePath: vscodeExePath,
    launchArgs: ["--disable-extensions", workspacePath],
    extensionTestsEnv: {
      [testFilterEnvironmentVariable]: args[0],
      // HACK(strager): Silence lots of log noise generated by VS Code.
      NODE_NO_WARNINGS: "1",
    },
    platform: getVSCodePlatform(target),
  });
}
exports.mainAsync = mainAsync;

function getVSCodePlatform(target) {
  let vscodePlatformsByPlatformAndArch = {
    "darwin-arm64": "darwin-arm64",
    "darwin-x64": "darwin",
    "linux-arm": "linux-armhf",
    "linux-arm64": "linux-arm64",
    "linux-x64": "linux-x64",
    "win32-ia32": "win32-archive",
    "win32-x64": "win32-x64-archive",
  };
  let platformAndArch = `${target.platform}-${target.arch}`;
  if (
    !Object.prototype.hasOwnProperty.call(
      vscodePlatformsByPlatformAndArch,
      platformAndArch
    )
  ) {
    throw new Error(
      `Unknown platform and architecture: ${platformAndArch}\nSupported: ${Object.keys(
        vscodePlatformsByPlatformAndArch
      ).join(", ")}`
    );
  }
  return vscodePlatformsByPlatformAndArch[platformAndArch];
}

// Returns the path to the Visual Studio Code executable (e.g. code.exe).
async function installVSCodeAsync(version, target) {
  let vscodePlatform = getVSCodePlatform(target);
  let exePath = await vscodeTestDownload.downloadAndUnzipVSCode(
    version,
    vscodePlatform
  );
  // HACK(strager): downloadAndUnzipVSCode assumes x64/x86_64/amd64. Fix the path for other architectures.
  exePath = exePath.replace("/VSCode-linux-x64/", `/VSCode-${vscodePlatform}/`);
  return exePath;
}

function getVSCodeVersionForTarget(target) {
  if (target.arch === "arm" || target.arch === "arm64") {
    // HACK(strager): 1.49.x does not exist for darwin-arm64 or linux-arm or linux-arm64.
    if (target.platform === "darwin") {
      return "1.54.3";
    } else {
      return "1.50.1";
    }
  } else {
    return "1.49.0";
  }
}

function parseNodePlatformAndArchitecture(s) {
  let parts = s.split("-", 2);
  return { arch: parts[1], platform: parts[0] };
}

if (require.main === module) {
  mainAsync().catch((error) => {
    console.log(error.stack);
    process.exit(1);
  });
}

// quick-lint-js finds bugs in JavaScript programs.
// Copyright (C) 2020  Matthew "strager" Glazar
//
// This file is part of quick-lint-js.
//
// quick-lint-js is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// quick-lint-js is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with quick-lint-js.  If not, see <https://www.gnu.org/licenses/>.
